#ifndef _PAGING_H_
#define _PAGING_H_

#define PAGE_FLAGS_READ		0x01
#define PAGE_FLAGS_WRITE	0x02
#define PAGE_FLAGS_EXEC		0x04
#define PAGE_FLAGS_USER		0x08

#define PAGEDIR_ENTRY(x)	((dword) x >> 22)
#define PAGETAB_ENTRY(x)	(((dword) x >> 12) & 0x3FF)

class Page {
public:
	dword present	: 1;	// Page present in memory
	dword rw	: 1;	// Read-only if clear, readwrite if set
	dword user	: 1;	// Supervisor level only if clear
	dword accessed	: 1;	// Has the page been accessed since last refresh?
	dword dirty	: 1;	// Has the page been written to since last refresh?
	dword unused	: 7;	// Amalgamation of unused and reserved bits
	dword frame	: 20;	// Frame address (shifted right 12 bits)
};

class PageTable {
public:
	Page Pages[1024];
};

class PageDirectory {
public:
	dword Virtual2Physical(dword virt);
	int MapPage(word mode, dword virt, dword phys);
	int UnmapPage(dword virt);
	int MapMemory(word mode, dword virt, dword phys, dword len);
	int UnmapMemory(dword virt, dword len);
	
	PageTable *Tables[1024];
	dword TablesPhys[1024];
	dword PhysicalAddress;
};

class Paging {
public:
	static void Init();

	static PageDirectory kPgDir;
};

#endif
